package com.gengzp.rpc.interceptor;

import com.gengzp.rpc.core.RpcRemoteTransactionCoreFunc;
import com.gengzp.rpc.core.RpcRequestIdentificationCoreFunc;
import com.gengzp.rpc.exception.RpcException;
import com.gengzp.rpc.model.requestIdentification.RpcRequestIdentification;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.util.UUID;

import static com.gengzp.rpc.constants.RpcRequestHeaderFieldNameConstants.REQUEST_ID;
import static com.gengzp.rpc.constants.RpcUriConstants.OPTIONS_REQUEST_URI;

/**
 * @ClassName RpcRequestIdentificationInterceptor
 * @Description rpc模块请求标识拦截器
 * @Author gengzp
 * @Date 2025/8/22 14:53
 */
@Component
public class RpcRequestIdentificationInterceptor implements HandlerInterceptor, Ordered {

    @Autowired
    private RpcRequestIdentificationCoreFunc rpcRequestIdentificationCoreFunc;

    @Autowired
    private RpcRemoteTransactionCoreFunc rpcRemoteTransactionCoreFunc;

    /**
     * 请求调用前执行逻辑
     */
    @Override
    @SuppressWarnings("NullableProblems")
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws RpcException {
        // 预检请求直接放行, 不处理
        if (request.getRequestURI().contains(OPTIONS_REQUEST_URI)) {
            return true;
        }

        // 是否是初始请求标识
        boolean initialRequestFlag = false;

        // 获取请求头中的requestId, 若为空表示当前请求是初始请求, 生成一个requestId, 否则表示为远程调用, 加入这个requestId
        String requestId = request.getHeader(REQUEST_ID);
        if (requestId == null || requestId.isBlank()) {
            initialRequestFlag = true;
            requestId = UUID.randomUUID().toString().replace("-", "");
        }

        // 将请求标识信息全部保存到线程变量
        rpcRequestIdentificationCoreFunc.saveRequestId(requestId);
        rpcRequestIdentificationCoreFunc.saveEnableRemoteTransactionFlag(false);
        rpcRequestIdentificationCoreFunc.saveInitialRequestFlag(initialRequestFlag);
        return true;
    }

    @Override
    @SuppressWarnings("NullableProblems")
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        RpcRequestIdentification requestIdentification = rpcRequestIdentificationCoreFunc.getCurrentRequestIdentification();

        // 初始请求, 并且加入了远程事务, 则进入特殊处理逻辑
        if (requestIdentification.getInitialRequestFlag() && requestIdentification.getEnableRemoteTransactionFlag()) {
            // 如果发生了异常, 则执行回滚逻辑
            if (ex != null) {
                rpcRemoteTransactionCoreFunc.doExecuteRemoteTransactionRollback();
            }
            // 清空缓存中的事务信息
            rpcRemoteTransactionCoreFunc.doClearRemoteTransactionCache();
        }

        // 请求处理完成, 清理线程变量中的请求标识信息上下文
        rpcRequestIdentificationCoreFunc.clearCurrentRequestIdentification();
    }

    @Override
    public int getOrder() {
        return 0;
    }

}
